package com.derbysoft.lowcostadapter.dswitch2.translator.impl;

import com.derbysoft.lowcostadapter.commons.dto.Cancel;
import com.derbysoft.lowcostadapter.commons.dto.CancelRequest;
import com.derbysoft.lowcostadapter.commons.exception.InvalidFieldException;
import com.derbysoft.lowcostadapter.commons.exception.ReservationNotFound;
import com.derbysoft.lowcostadapter.commons.model.Reservation;
import com.derbysoft.lowcostadapter.commons.repository.ReservationRepository;
import com.derbysoft.lowcostadapter.dswitch2.translator.Translator;
import com.derbysoft.remote.dswitch.core.GenericRQ;
import com.derbysoft.remote.dswitch.generic.constants.UniqueIDType;
import com.derbysoft.remote.dswitch.hotel.dto.CancelRQ;
import com.derbysoft.remote.dswitch.hotel.dto.HotelReservationIDDTO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

@Component("ds2CancelRQTranslator")
public class CancelRQTranslatorImpl extends AbstractRQTranslator implements Translator<GenericRQ<CancelRQ>, Cancel, Void> {
    @Autowired
    private ReservationRepository reservationRepository;

    @Override
    public Cancel translate(GenericRQ<CancelRQ> rq, Void hotel) {
        Cancel cancel = new Cancel();
        cancel.setCancelRequest(translateCancelRequest(rq));
        return cancel;
    }

    private CancelRequest translateCancelRequest(GenericRQ<CancelRQ> rq) {
        CancelRQ cancelRQ = rq.getPayload();
        CancelRequest cancelRequest = new CancelRequest();
        cancelRequest.setLoginDetails(createLoginDetails(rq.getHeader().getSource().getUniqueID().getId()));
        cancelRequest.setBookingReference(translateBookingReference(cancelRQ.getHotelReservationIDs()));
        return cancelRequest;
    }

    private String translateBookingReference(List<HotelReservationIDDTO> hotelReservationIDs) {
        for (HotelReservationIDDTO hotelReservationID : hotelReservationIDs) {
            if (hotelReservationID.getResIDType() == UniqueIDType.ERSP) {
                Reservation reservation = reservationRepository.findByErsp(hotelReservationID.getResIDValue());
                if (reservation == null || StringUtils.isNotBlank(reservation.getCancellationReference())) {
                    throw new ReservationNotFound(hotelReservationID.getResIDValue());
                }
                return reservation.getBookingReference();
            }
        }
        throw new InvalidFieldException("hotelReservationIDs", hotelReservationIDs.toString());
    }

    public void setReservationRepository(ReservationRepository reservationRepository) {
        this.reservationRepository = reservationRepository;
    }
}
